#[cfg(not(target_arch = "wasm32"))]
use native::{http_client::HttpClient, sse_client::SseClient, ws_client::WsClient};

#[cfg(target_arch = "wasm32")]
use wasm::{http_client::HttpClient, sse_client::SseClient, ws_client::WsClient};

#[cfg(not(target_arch = "wasm32"))]
pub mod native;

#[cfg(target_arch = "wasm32")]
pub mod wasm;

pub mod param;

pub trait ServerAddressManager {
    fn get_server_addr(&self, name: &str) -> &str;
}

pub trait DutyClient<C, S>
where
    C: HttpClient + SseClient + WsClient,
    S: ServerAddressManager,
{
    fn new(client: C, service_manger: S) -> Self;
}

pub trait RequestParamSign<DefinedType> {
    type Input;
}

impl<T> RequestParamSign<()> for T {
    type Input = ();
}

macro_rules! impl_tuple_request_param_sign {
    ($($ident: ident,)*) => {
        impl<$($ident,)* T> RequestParamSign<($($ident,)*)> for T
        where
            $(T: RequestParamSign<$ident>,)*
        {
            type Input = ($(<T as RequestParamSign<$ident>>::Input,)*);
        }
    };
}
impl_tuple_request_param_sign!(A1,);
impl_tuple_request_param_sign!(A1, A2,);
impl_tuple_request_param_sign!(A1, A2, A3,);
impl_tuple_request_param_sign!(A1, A2, A3, A4,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13,);
impl_tuple_request_param_sign!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,);
impl_tuple_request_param_sign!(
    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
);
impl_tuple_request_param_sign!(
    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16,
);

pub trait ResponseParamSign<DefinedType> {
    type Output;
}

pub trait WebsocketParamSign<DefinedType> {
    type SendMessage;
    type ReceiveMessage;
}
